다이내믹 상자넣기-백준 1965번

전형적인 DP, 가장 긴 증가하는 부분수열

Category: 알고리즘 문제풀이 → 동적 프로그래밍
Difficulty: 중급
Date: 2026-01-26
Read Time: 4 mins read
Views: 조회

상자넣기

시간 제한 메모리 제한 제출 정답 맞힌 사람 정답 비율
2 초 128 MB 27372 13756 11525 50.872%

문제

정육면체 모양의 상자가 일렬로 늘어서 있다. 상자마다 크기가 주어져 있는데, 앞에 있는 상자의 크기가 뒤에 있는 상자의 크기보다 작으면, 앞에 있는 상자를 뒤에 있는 상자 안에 넣을 수가 있다.
예를 들어 앞에서부터 순서대로 크기가 (1, 5, 2, 3, 7)인 5개의 상자가 있다면, 크기 1인 상자를 크기 5인 상자에 넣고, 다시 이 상자를 크기 7인 상자 안에 넣을 수 있다. 하지만 이렇게 상자를 넣을 수 있는 방법은 여러 가지가 있을 수 있다. 앞의 예에서 차례대로 크기가 1, 2, 3, 7인 상자를 선택하면 총 4개의 상자가 한 개의 상자에 들어가게 된다.

상자의 크기가 주어질 때, 한 번에 넣을 수 있는 최대의 상자 개수를 출력하는 프로그램을 작성하시오.

입력

파일의 첫 번째 줄은 상자의 개수 n (1 ≤ n ≤ 1000)을 나타낸다.
두 번째 줄에는 각 상자의 크기가 순서대로 주어진다. 상자의 크기는 1,000을 넘지 않는 자연수이다.

출력

첫째 줄에 한 줄에 넣을 수 있는 최대의 상자 개수를 출력한다.

예제 입력 1


8
1 6 2 5 7 3 5 6

예제 출력 1


5

예제 입력 2


10
1 2 3 4 5 6 7 8 9 10

예제 출력 2


10

출처

  • 잘못된 데이터를 찾은 사람: tncks0121
  • 빠진 조건을 찾은 사람: luniro

알고리즘 분류

  • 다이나믹 프로그래밍
  • 가장 긴 증가하는 부분 수열 문제

풀이

이 문제의 풀이는 간단하다. 이것은 특정 상자 이전에 있는 그 상자보다 작은 것을 for문으로 순회하면서 그러한 상태를 발견하면 현재 상자 위치의 상자 수보다 이전 상자 위치의 상자 수 + 1 이 더 큰지 확인 후 최대를 골라 상태를 업데이트한다. 아래 코드를 보면 아주 명확하게 나와 있다. 이러한 조건은

  • 상자들을 순회해야 하니 전범위 인덱싱
    • 상자들보다 이전에 있는 것을 순회해야 하니 부분 인덱싱
    • 조건에 맞는 처리

를 하는 것이 중요하다. 비슷한 유형의 문제를 풀어 보는 것이 중요하고, 이런 유형의 수열 문제는 템플릿으로 암기하는 것 역시 권장한다.

코드

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

#define MAX(x, y) ((x) > (y)) ? (x): (y)

int main() {
    int n;
    scanf("%d", &n);


    int *arr = malloc(sizeof(int) * n);
    int boxes = 0;
    int *total_boxes = calloc(n, sizeof(int));

    for(int i = 0; i < n; i++) {
        scanf("%d", arr + i);
    }

    for(int k = 0; k < n; k++) {
        for(int i = 0; i < k; i++) {
            if(arr[i] < arr[k]) {
                total_boxes[k] = MAX(total_boxes[i] + 1, total_boxes[k]);
            }
        }
    }

    for(int i = 0; i < n; i++) {
        boxes = MAX(total_boxes[i], boxes);
    }
    ++boxes;
    printf("%d", boxes);
    free(total_boxes);
    free(arr);
    return 0;
}

Document Classification

Keywords
동적 프로그래밍 DP 백준 알고리즘 수열
Difficulty
중급
Permalink
https://gg582.github.io/codingtest/2026-01-26-%5B%EB%8B%A4%EC%9D%B4%EB%82%B4%EB%AF%B9%5D-%EC%83%81%EC%9E%90%EB%84%A3%EA%B8%B0-%EB%B0%B1%EC%A4%80-1965%EB%B2%88/

Citation

이윤진(Lee Yunjin) (2026). [다이내믹] 상자넣기-백준 1965번. 윤진의 IT 블로그. Retrieved from https://gg582.github.io/codingtest/2026-01-26-%5B%EB%8B%A4%EC%9D%B4%EB%82%B4%EB%AF%B9%5D-%EC%83%81%EC%9E%90%EB%84%A3%EA%B8%B0-%EB%B0%B1%EC%A4%80-1965%EB%B2%88/
── 하략 ──